/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-03
 * V4.0
 */
package com.jphenix.driver.json;

import java.io.CharArrayWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.jphenix.share.tools.Base64;
/**
 * Json 对象
 * 
 * 如果放入数字类型的值，输出时不带双引号。如果放入布尔值，输出不带双引号的 true 或 false
 * 如果想输出带双引号的数字，或者布尔，放入前转成字符串类型破里斯。
 * 
 * 2018-08-10 增加了children方法，与childs功能相同。以后既可以使用children方法，还可以使用错别字方法
 * 2018-11-29 增加了输出字符串中，如果存在换行符，则转义换行符
 * 2019-03-05 增加了两个获取当前节点主键数组(keys())和序列的方法(keyList())
 * 2019-06-04 如果设置输出的值不加双引号，不论输出值是什么，都不加双引号
 * 2019-06-17 完善了日志
 * 2019-06-25 修改了toObject中报空指针错误
 * 2019-10-09 去掉了一些无用的注释
 * 2020-03-04 修改了解析\\\" 时，这种连续转义字符处理错误
 * 2020-07-14 废弃了方法setOutNoStringFormat,改用 outNoFormat，增加了 standardFormat 方法
 * 2020-07-30 修改了standardFormat设置值时写死为true的错误
 * 2021-06-11 增加了put方法，设置map值
 * 2021-07-07 减少了当前类依赖其它类，便于该类单独移植到其他项目
 * 2021-09-30 为put方法增加传入字符串数组值
 * 2021-10-02 修改了序列元素时数组值时，输出错误格式的问题
 * 2022-10-20 增加了设置值时过滤特殊字符，避免拼装json时格式报错
 * 2022-10-21 优化并简化了代码
 * 2024-03-29 修改了设置带\字符的值时，输出文本没有做转义的错误
 * 2024-06-09 修改了程序抛异常的地方
 * 
 * @author mbg
 * 2014-2-26
 */
public class Json {

  protected boolean                        isList    = false; //是否为序列容器
  protected LinkedHashMap<String,Object>   mapValue  = null;  //map容器
  protected ArrayList<Object>              listValue = null;  //list容器
  protected Json                           parent    = null;  //父对象
  protected String                         delimiter = "\"";  //分隔符
  
  /*
   * 在解析别人的Json字符串时，有时的值为空关键字
   * 之前被当前类强制转换为空字符串
   * 
   * 后来遇到问题，发送Json字符串的程序对json字符串做了签名
   * 这就导致解析字符串时验签失败（空关键字被解析为空字符串导致与原文不符）
   * 
   * 所以增加了以下变量允许空关键字
   * 
   */
  protected Boolean allowNullValue = null; //是否允许空值 （不返回“” 而是返回  null 关键字）
  protected String  nullKey        = null; //空值关键字
  protected Boolean noFormat       = null; //输出的所有值都不带双引号，通常用在输出的值是javascript的方法名，这个方法名不能加双引号
  protected Boolean standardFormat = null; //是否输出标准格式，输出的值，如果是数字，或者布尔，则不带双引号
  
  /**
   * 构造函数
   * @author mbg
   */
  public Json() {
    super();
  }
  
  /**
   * 构造函数
   * @author MBG
   */
  public Json(Object value) {
    super();
    set(value);
  }
  
  /**
   * 构造函数
   * @param jsonStr json字符串攒
   * @author mbg
   */
  public Json(String jsonStr) {
    super();
    setString(jsonStr); //设置字符串
  }
  
  /**
   * 构造函数
   * @author MBG
   */
  public Json(String jsonStr,boolean allowNullValue) {
    super();
    setString(jsonStr);
    setAllowNullValue(allowNullValue);
  }
  
  /**
   * 设置是否允许返回空值关键字
   * 
   * 默认不允许，被强制转换为  "" 空字符串
   * 如果设置为允许，就返回 null
   * 
   * @param enabled 是否允许返回空值关键字（默认不允许）
   * @return 当前类实例
   * 2016年9月29日
   * @author MBG
   */
  public Json setAllowNullValue(boolean enabled) {
    allowNullValue = enabled;
    return this;
  }
  
  /**
   * 设置是否允许返回非字符串值时，不带双引号
   * 
   * （注意！：目前改为输出的值都不带双引号，无论是不是字符串）
   * 
   * 该方法已经废弃，因为名字跟实际功能不相符
   * 
   * @param enabled 是否允许
   * @return 当前类实例
   * 2018年3月7日
   * @author MBG
   */
  @Deprecated
  public Json setOutNoStringFormat(boolean enabled) {
    noFormat = enabled;
    return this;
  }
  
  /**
   * 设置输出的Json字符串中，所有的值都不加双引号
   * 
   * 比如输出的json字符串是给javascript用的，其中的字符串值是javascript的方法名
   * 这个方法名不能加双引号，导致js方法不能正常调用
   * 
   * @return 当前类实例
   * 2020年7月14日
   * @author MBG
   */
  public Json outNoFormat() {
    noFormat = true;
    return this;
  }
  
  /**
   * 设置是否输出的Json字符串中，所有的值都不加双引号
   * 
   * 比如输出的json字符串是给javascript用的，其中的字符串值是javascript的方法名
   * 这个方法名不能加双引号，导致js方法不能正常调用
   * 
   * @param enabled 是否输出的Json字符串中，所有的值都不加双引号
   * @return 当前类实例
   * 2020年7月14日
   * @author MBG
   */
  public Json outNoFormat(boolean enabled) {
    noFormat = enabled;
    return this;
  }
  
  /**
   * 是否输出标准格式的json字符串
   * 
   * 默认输出所有的值都带双引号。
   * 
   * 调用该方法后，输出的值如果是数字或者布尔，则不带双引号
   * 
   * @return  当前类实例
   * 2020年7月14日
   * @author MBG
   */
  public Json outStandardFormat() {
    standardFormat = true;
    return this;
  }
  
  /**
   * 是否输出标准格式的json字符串
   * 
   * 默认输出所有的值都带双引号。
   * 
   * 如果参数enabled为true，输出的值如果是数字或者布尔，则不带双引号
   * 
   * @param enabled 是否输出标准格式的json字符串
   * @return        当前类实例
   * 2020年7月14日
   * @author MBG
   */
  public Json outStandardFormat(boolean enabled) {
    standardFormat = enabled;
    return this;
  }
  
  /**
   * 返回是否允许返回空值关键字
   * @return 是否允许返回空值关键字
   * 2016年9月29日
   * @author MBG
   */
  public boolean isAllowNullValue() {
    if(allowNullValue!=null) {
      return allowNullValue;
    }
    if(parent!=null && !parent.equals(this)) {
      return parent.isAllowNullValue();
    }
    return false;
  }
  
  /**
   * 返回是否允许当值为非字符串类型时，不带双引号
   * 
   * 注意：目前已经改为：输出的任何值都不带双引号！！！
   * 
   * 该方法已经废弃，因为方法名跟实际功能不符
   * 
   * @return 是否允许
   * 2018年3月7日
   * @author MBG
   */
  @Deprecated
  public boolean isOutNoStringFormat2() {
    if(noFormat==null) {
      if(parent!=null && !parent.equals(this)) {
        return parent.isOutNoStringFormat2();
      }
      return false;
    }
    return noFormat;
  }
  
  /**
   * 返回是否输出json中的值，都不带双引号
   * 
   * 通常用在返回的json字符串是给javascript用的，其中的值是js的方法名
   * 这样这个值是不能带双引号的
   * 
   * @return 是否输出json中的值，都不带双引号
   * 2020年7月14日
   * @author MBG
   */
  public boolean isNoFormat() {
    if(noFormat==null) {
      if(parent!=null && !parent.equals(this)) {
        return parent.isNoFormat();
      }
      return false;
    }
    return noFormat;
  }
  
  /**
   * 输出的json中的值，是不是标准格式的json格式
   * 
   * 标准格式：如果json中的值是数字或者布尔值，则不带双引号。
   * 
   * 非标准格式： 输出的json中的值，无论什么格式，都带双引号
   * 
   * @return 输出的json中的值，是不是标准格式的json格式
   * 2020年7月14日
   * @author MBG
   */
  public boolean isStandardFormat() {
    if(standardFormat==null) {
      if(parent!=null && !parent.equals(this)) {
        return parent.isStandardFormat();
      }
      return false;
    }
    return standardFormat;
  }
  
  /**
   * 设置空值关键字（与setAllowNullValue配合使用）
   * @param nullKey 空值关键字
   * @return 当前类实例
   * 2016年9月29日
   * @author MBG
   */
  public Json setNullKey(String nullKey) {
    if(parent==null || parent.equals(this)) {
      this.nullKey = nullKey;
    }else {
      parent.setNullKey(nullKey);
    }
    return this;
  }
  
  /**
   * 返回空值关键字（默认 null） 与isAllowNullValue配合使用
   * @return 空值关键字
   * 2016年9月29日
   * @author MBG
   */
  public String getNullKey() {
    if(parent==null || parent.equals(this)) {
      if(nullKey==null) {
        return "null";
      }
      return nullKey;
    }
    return parent.getNullKey();
  }
  
  /**
   * 设置分隔符
   * @param delimiter 分隔符
   * @return 返回当前类实例
   * 2014年11月25日
   * @author 马宝刚
   */
  public Json setDelimiter(String delimiter) {
      this.delimiter = delimiter;
      return this;
  }
  
  /**
   * 返回当前子节点数量
   * @return 当前子节点数量
   * 2015年3月18日
   * @author 马宝刚
   */
  public int size() {
      if(isList) {
          return getChildList().size();
      }
      return getValueMap().size();
  }
  
  /**
   * 获取当前分隔符
   * @return 当前分隔符
   * 2014年11月25日
   * @author 马宝刚
   */
  public String getDelimiter() {
      return delimiter;
  }
  
  /**
   * 获取父对象（上一级Json）
   * @return 父对象
   * 2014年4月10日
   * @author 马宝刚
   */
  public Json getParent() {
      return parent;
  }
  
  /**
   * 获取父对象（上一级Json）
   * @return 父对象
   * 2014年4月10日
   * @author 马宝刚
   */
  public Json parent() {
      return parent;
  }
  
  /**
   * 获取父对象（上一级Json）
   * @return 父对象
   * 2014年4月10日
   * @author 马宝刚
   */
  public Json p() {
      return parent;
  }
  
  /**
   *  通过JSon字符串获取JSon java对象
   * @param jsonStr JSon字符串
   * 2014-2-26
   * @author mbg
   */
  public static Json newJson(String jsonStr) {
    return new Json(jsonStr);
  }
  
  /**
   * 构造新的Json类，并设置数据值对象
   * @param value 数据值对象
   * @return 设置数据后的Json对象
   * 2016年10月17日
   * @author MBG
   */
  public static Json newJson(Object value) {
    return new Json(value);
  }
  
  /**
   * 清空内容
   * @return 当前类实例
   * 2014-2-26
   * @author mbg
   */
  public Json clear() {
    mapValue = null;
    listValue = null;
    return this;
  }
  
  /**
   * 该Json对象是否为空
   * @return 是否为空
   * 2014-2-26
   * @author mbg
   */
  public boolean isEmpty() {
    if(mapValue!=null) {
      return mapValue.isEmpty();
    }
    if(listValue!=null) {
      return listValue.isEmpty();
    }
    return true;
  }
  
  /**
   * 该对象值是否为序列
   * @return 是否为序列
   */
  public boolean isList() {
    return isList;
  }
  
  /**
   * 设置该对象值是否为序列
   * @param isList 该对象值是否为序列
   * 2015年4月9日
   * @author 马宝刚
   */
  public void setList(boolean isList) {
      this.isList = isList;
  }
  
  /**
   * 设置json字符串
   * @param jsonStr json字符串攒
   * @return json对象
   * 2014-2-26
   * @author mbg
   */
  public Json setString(String jsonStr) {
    clear();
    if(jsonStr==null || jsonStr.length()<1) {
      return this;
    }
    if(jsonStr.startsWith("@b64@")) {
      jsonStr = new String(Base64.decode(jsonStr.getBytes(),5,jsonStr.length()-5));
    }
    //转换为字符数组
    char[] msgChars = jsonStr.trim().toCharArray();
    if(msgChars[0]=='[') {
      //序列
      parseList(msgChars,1,this);
    }else {
      //容器
      parseMap(msgChars,1,this);
    }
    return this;
  }
  
  /**
   * 将指定json对象加入当前json序列中
   * @param json  子json对象
   * @return 当前json对象
   * 2014-2-26
   * @author mbg
   */
  public Json addJson(Json json) {
    return addJson(json,-1);
  }
  
  /**
   * 将指定json对象加入当前json序列中
   * @param json  子json对象
   * @param index 子对象放入序列中的位置
   * @return 当前json对象
   * 2014-2-26
   * @author mbg
   */
  public Json addJson(Json json,int index) {
    isList = true;
    if(listValue==null) {
        listValue = new ArrayList<Object>();
    }
    if(json==null) {
      return this;
    }
    json.parent = this;
    if( index>-1) {
        listValue.add(index,json);
    }else {
        listValue.add(json);
    }
    return this;
  }
  
    /**
     * 添加一个子json对象，并返回这个子对象
     * @return 子json对象
     * 2014年4月10日
     * @author 马宝刚
     */
  public Json addJson() {
    return addJson(-1);
  }
  
  /**
   * 添加一个子json对象，并返回这个子对象
   * @param index 子对象放入序列中的位置
   * @return 子json对象
   * 2014年4月10日
   * @author 马宝刚
   */
  public Json addJson(int index) {
    isList = true;
    if(listValue==null) {
      listValue = new ArrayList<Object>();
    }
    //构建子Json对象
    Json cJson = new Json();
    cJson.parent = this;
    if( index >-1) {
      listValue.add(index,cJson);
    }else {
      listValue.add(cJson);
    }
    return cJson;
  }
  
  /**
   * 将子Json对象放入容器，并返回这个子Json对象 简称：put
   * @param key  对应的主键
   * @return         子Json对象
   * 2014年4月10日
   * @author 马宝刚
   */
  public Json putJson(String key) {
    //构建子Json对象
    Json cJson = new Json();
    cJson.parent = this;
    putJson(key,cJson);
    return cJson;
  }
  
  /**
   * 将子Json对象放入容器，并返回这个子Json对象 全称：putJson
   * @param key  对应的主键
   * @return         子Json对象
   * 2014年4月10日
   * @author 马宝刚
   */
  public Json put(String key) {
    //构建子Json对象
    Json cJson = new Json();
    cJson.parent = this;
    putJson(key,cJson);
    return cJson;
  }

  /**
   * 将指定json对象放入当前json对象容器中
   * @param key  json子对象对应的主键
   * @param json  json子对象
   * @return 当前类实例
   * 2014-2-26
   * @author mbg
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
    public Json putJson(String key,Json json) {
    if(json==null) {
      return this;
    }
    json.parent = this;
    isList = false;
    if(mapValue==null) {
      mapValue = new LinkedHashMap();
    }
    mapValue.put(key,json);
    return this;
  }
  
  /**
   * 将当前Json对象中累加数组元素值 （方法同add）
   * @param value 数组元素值
   * @return 当前Json对象
   * 2014年6月24日
   * @author 马宝刚
   */
  public Json addValue(Object value) {
      return add(value);
  }
  
  /**
   * 将当前Json对象中累加数组元素值 （方法同addValue）
   * @param value 数组元素值
   * @return 当前Json对象
   * 2014年6月24日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Json add(Object value) {
    isList = true;
    if (listValue == null) {
      listValue = new ArrayList<Object>();
    }
    if (value instanceof String) {
      listValue.add(value);
    } else if (value instanceof Map) {
      addJson().putValueMap((Map) value);
    } else if (value instanceof List) {
      for (Object ele : ((List) value)) {
    	if(ele instanceof String[]) {
    		// 需要在当前节点中构造子节点来存放字符串数组值
    		addValueArrl((String[])ele,true);
    	}else {
    		add(ele);
    	}
      }
    } else if (value instanceof String[]) {
      addValueArrl((String[]) value);
    } else if (value instanceof Json) {
      listValue.add(value);
    } else {
      listValue.add(value);
    }
    return this;
  }
  
  /**
   * 添加一个子json对象，并返回这个子对象
   * @return 子json对象
   * 2016年10月9日
   * @author MBG
   */
  public Json add() {
    return addJson(-1);
  }
  
  /**
   * 将对象值设置到当前Json中
   * @param value 对象值，只能是 Json List Map
   * @return 当前类实例
   * 2016年10月1日
   * @author MBG
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public Json set(Object value) {
    if(value==null) {
      return this;
    }
    if(value instanceof Json) {
      listValue = new ArrayList<Object>();
      listValue.add(value);
    }else if(value instanceof List) {
      listValue = new ArrayList<Object>();
      return addValueList((List)value);
    }
    if(value instanceof Map) {
      return putValueMap((Map)value);
    }
    return this;
  }
  
  /**
   * 将容器中的内容作为元素加入到json中
   * 
   * [
   *   {Map}
   * ,{Map}
   * ]
   * @param valueMap 信息容器
   * @return 当前类实例
   * 2014年8月7日
   * @author 马宝刚
   */
  public Json addMapValue(Map<String,String> valueMap) {
    Json cJson = addJson();
    cJson.putValueMap(valueMap);
    //返回新增的子对象，而不是当前的对象
    //当前对象本身就有，但新增的子对象如果不在这里返回，
    //回头不太容易获取
    return cJson;
  }
  
  
  /**
   * 将字符串解析为子对象值，将子对象放入当前json对象序列中
   * @param jsonStr 子对象json字符串
   * @return json字符串对应的子json对象
   * 2014-2-26
   * @author mbg
   */
  public Json addJson(String jsonStr) {
    return addJson(jsonStr,-1);
  }
  
  /**
   * 将字符串解析为子对象值，将子对象放入当前json对象序列中
   * @param jsonStr 子对象json字符串
   * @param index 子对象放入序列中的位置
   * @return json字符串对应的子json对象
   * 2014-2-26
   * @author mbg
   */
  public Json addJson(String jsonStr,int index) {
    isList = true;
    if(listValue==null) {
      listValue = new ArrayList<Object>();
    }
    if(jsonStr==null || jsonStr.length()<1) {
      return this;
    }
    //构建子对象
    Json cJson = new Json();
    cJson.setString(jsonStr);
    cJson.parent = this;
    if(index>-1) {
      listValue.add(index,cJson);
    }else {
      listValue.add(cJson);
    }
    return cJson;
  }
  
  /**
   * 将字符串解析为子json对象，放入当前json容器中
   * @param key    子json对象对应的主键
   * @param jsonStr  json字符串
   * @return 子json对象
   * 2014-2-26
   * @author mbg
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
    public Json putJsonString(String key,String jsonStr) {
    if(key==null || key.length()<1 || jsonStr==null || jsonStr.length()<1) {
      return this;
    }
    isList = false;
    if(mapValue==null) {
      mapValue = new LinkedHashMap();
    }
    //构建子对象
    Json cJson = new Json();
    cJson.setString(jsonStr);
    cJson.parent = this;
    mapValue.put(key,cJson);
    return cJson;
  }
  
  /**
   * 判断当前层级中，是否存在该主键（只针对map类型）
   * @param key  判断主键
   * @return 是否存在
   * 2015年3月2日
   * @author 马宝刚
   */
  public boolean containsKey(String key) {
    if(mapValue==null) {
      return false;
    }
    return mapValue.containsKey(key);
  }
  
  /**
   * 判断当前层级中，是否存在该值
   * 优先map，然后是list
   * @param value 比较值
   * @return 是否存在
   * 2015年3月2日
   * @author 马宝刚
   */
  public boolean containsValue(String value) {
    if(mapValue!=null && mapValue.containsValue(value)) {
      return true;
    }
    return listValue != null && listValue.contains(value);
  }
  
  /**
   * 将值放入当前json层级中
   * @param key  主键
   * @param value 值
   * @return 当前类实例
   * 2014-2-26
   * @author mbg
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Json putString(String key,String value) {
    if(key==null || key.length()<1) {
      return this;
    }
    isList = false;
    if(mapValue==null) {
      mapValue = new LinkedHashMap();
    }
    mapValue.put(key,str(value));
    return this;
  }
    
  /**
   * 放入值 （方法同 put）
   * @param key    值主键
   * @param value 值
   * @return 当前类实例
   * 2015年12月3日
   * @author 马宝刚
   */
  public Json putValue(String key,Object value) {
    return put(key,value);
  }
    
  /**
   * 放入值 （方法同putValue）
   * @param key    值主键
   * @param value 值
   * @return 当前类实例
   * 2015年12月3日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Json put(String key, Object value) {
    if (value == null) {
      return this;
    }
    if (value instanceof String) {
      if (key == null || key.length() < 1) {
        return this;
      }
      putString(key, (String) value);
    } else if (value instanceof Map) {
      if (key == null || key.length() < 1) {
        putValueMap((Map) value);
      } else {
        putJson(key).putValueMap((Map) value);
      }
    } else if(value instanceof String[]) {
    	putJson(key).addValueArrl((String[])value);
    } else if (value instanceof List) {
      if (key == null || key.length() < 1) {
        addValueList((List) value);
      } else {
        putJson(key).addValueList((List) value);
      }
    } else if (value instanceof Json) {
      if (key == null || key.length() < 1) {
        addJson((Json) value);
      } else {
        putJson(key, (Json) value);
      }
    } else {
      if (key == null || key.length() < 1) {
        isList = true;
        if (listValue == null) {
          listValue = new ArrayList<Object>();
        }
        listValue.add(value);
      } else {
        isList = false;
        if (mapValue == null) {
          mapValue = new LinkedHashMap();
        }
        mapValue.put(key, value);
      }
    }
    return this;
  }
    
    
  /**
   * 将容器放入JSon中
   * @param valueMap 容器
   * @return 当前JSon类实例
   * 2014年4月17日
   * @author 马宝刚
   */
  @SuppressWarnings("unchecked")
  public Json putValueMap(Map<String,?> valueMap) {
    if (valueMap == null || valueMap.isEmpty()) {
      return this;
    }
    // 获取容器主键迭代器
    Iterator<?> keyIterator = valueMap.keySet().iterator();
    String keyStr = null; // 容器主键字符串
    Object key    = null; // 容器主键
    Object value  = null; // 容器值
    while (keyIterator.hasNext()) {
      key = keyIterator.next();
      if (key == null) {
        continue;
      }
      value = valueMap.get(key);
      if (value == null) {
        value = "";
      }
      keyStr = String.valueOf(key);
      if (value instanceof List<?>) {
        putJson(keyStr).addValueList((List<Object>) value);
      } else if (value instanceof Map<?, ?>) {
        putJson(keyStr).putValueMap((Map<String, Object>) value);
      } else if (value instanceof Json) {
        putJson(keyStr, (Json) value);
      } else {
        putString(keyStr, value.toString());
      }
    }
    return this;
  }

    /**
   * 将容器放入JSon中
   * @param valueMap 容器
   * @return 当前JSon类实例 2021年6月11日
   * @author 马宝刚
   */
  public Json put(Map<String, ?> valueMap) {
    return putValueMap(valueMap);
  }

  /**
   * 将序列放入Json中
   * @param valueList 序列
   * @return 当前Json类实例 2014年4月17日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Json addValueList(List valueList) {
    isList = true;
    if (valueList == null || valueList.size() < 1) {
      return this;
    }
    for (Object ele : valueList) {
      if (ele == null) {
        ele = "";
      }
      if (ele instanceof List<?>) {
        addJson().addValueList((List<Object>) ele);
      } else if (ele instanceof Map<?, ?>) {
        addJson().putValueMap((Map<String, Object>) ele);
      } else if (ele instanceof Json) {
        addJson((Json) ele);
      } else if(ele instanceof String[]) {
    	  // 需要在当前节点中增加子节点，在子节点中存放字符串数组值
    	  addValueArrl((String[])ele,true);
      } else {
        addValue(str(ele));
      }
    }
    return this;
  }
    
    
  /**
   * 向当前Json节点添加字符串数组元素
   * @param arrs 字符串数组值
   * @return 当前类实例 
   * 2017年9月13日
   * @author MBG
   */
  public Json addValueArrl(String[] arrs) {
	  return addValueArrl(arrs,false);
  }
  
  /**
   * 向当前Json节点添加字符串数组元素
   * @param arrs       字符串数组值
   * @param newChild   是否在新构造的子节点中增加数组元素（在解析List中的数组时会用到）
   * @return           当前类实例
   * 2021年10月2日
   * @author MBG
   */
  public Json addValueArrl(String[] arrs,boolean newChild) {
	    isList = true;
	    if (arrs == null || arrs.length < 1) {
	      return this;
	    }
	    Json cJson;
	    if(newChild) {
	    	cJson = addJson(); // 构造子对象
	    }else {
	    	cJson = this;
	    }
	    for (int i = 0; i < arrs.length; i++) {
	    	cJson.addValue(arrs[i]);
	    }
	    return this;
  }

  /**
   * 解析Json容器 mbg 2013-7-18 上午10:14:27
   * @param msgChars 待解析的字符数组
   * @param index    解析起始位
   * @param json     当前出来的对象
   * @return         解析后的位置
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  protected int parseMap(char[] msgChars, int index, Json json) {
    if (msgChars.length <= index || msgChars[index] == '}') {
      return index;
    }
    if (json.mapValue == null) {
      json.mapValue = new LinkedHashMap();
    }
    json.isList = false;

    boolean isInChar = false; // 是否为解析字符串模式
    boolean isSingleSign = false; // 字符串是否采用单引号定义
    boolean isNoSign = false; // 是否为无定义符号字符串（通常为数字，不用单引号或双引号定义）
    boolean isSpecSign = false; // 是否为转译字符
    boolean isParseKey = true; // 是否正在解析主键
    boolean hasSetObject = false; // 是否已经往序列中设置了对象
    int specSignCount = 0; // 连续转义符号个数

    CharArrayWriter key = new CharArrayWriter(); // 主键
    CharArrayWriter value = new CharArrayWriter(); // 值

    for (int i = index; i < msgChars.length; i++) {
      if (isInChar) {
        // 正在解析字符串中的内容
        if (msgChars[i] == '\\') {
          specSignCount++;
          // 标记为转译字符

          // 如果上一个字符也是转义字符
          if (specSignCount == 2) {
            specSignCount = 0;
            if (isParseKey) {
              key.write('\\');
            } else {
              value.write('\\');
            }
          }
          isSpecSign = true;
          continue;
        }
        specSignCount = 0;
        if (isSpecSign) {
          if (isParseKey) {
            key.write(msgChars[i]);
          } else {
            value.write(msgChars[i]);
          }
          isSpecSign = false;
        } else if ((msgChars[i] == '\'' && isSingleSign) || (msgChars[i] == '\"' && !isSingleSign)) {
          // 标记字符串结束
          isInChar = false;
          isSingleSign = false;
        } else if (msgChars[i] == ',' || msgChars[i] == ']' || msgChars[i] == '}') {
          if (isNoSign) {
            // 在没有引号做字符串定义时，遇到逗号，标记字符串结束
            i--; // 退回一个字符，由解析定义字符部分处理
            isInChar = false;
            isSingleSign = false;
          } else {
            // 该逗号或中括号是在字符串内的
            if (isParseKey) {
              key.write(msgChars[i]);
            } else {
              value.write(msgChars[i]);
            }
          }
        } else if (msgChars[i] == ':') {
          /*
           * 此处需要考虑无字符串标记符号，比如 { key : value } 需要遵守的原则，无符号信息中，key中不能有冒号，value中不能有逗号
           * 否则就被认为是json格式分隔符
           */
          if (isInChar) {
            // 在读取字符串信息
            if (isParseKey) {
              if (isNoSign) {
                // 如果字符串没有标识符（比如双引号，单引号），被认定字符串结束
                // 并且去掉后面的空格换行等无效字符
                isInChar = false;
                isSingleSign = false;
                isParseKey = false;
                value.reset();
                String fixKey = trim(key.toString(), " ", "\t", "\r", "\n");
                key.reset();
                try {
                  key.write(fixKey);
                } catch (Exception e) {
                }
              } else {
                // 如果该冒号在字符串标识符内，算作主键字符串的一部分（非json分隔符）
                key.write(msgChars[i]);
              }
            } else {
              // 无论有没有字符串标识符，都被认为是字符串的一部分
              value.write(msgChars[i]);
            }
          } else {
            if (isParseKey) {
              isInChar = false;
              isSingleSign = false;
              isParseKey = false;
              value.reset();
              if (isNoSign) {
                String fixKey = trim(key.toString(), " ", "\t", "\r", "\n");
                key.reset();
                try {
                  key.write(fixKey);
                } catch (Exception e) {
                }
              }
            } else {
              // 不可能走到这步
            }
          }
        } else {
          // 字符串中的内容
          if (isParseKey) {
            key.write(msgChars[i]);
          } else {
            value.write(msgChars[i]);
          }
        }
      } else {
        if (msgChars[i] > 0 && msgChars[i] < 33) {
          continue; // 过滤控制字符
        } else if (msgChars[i] == '\'') {
          // 单引号定义字符串，开始解析字符串中的内容
          isSingleSign = true;
          isInChar = true;
          isNoSign = false;
        } else if (msgChars[i] == '\"') {
          // 双引号定义字符串，开始解析字符串中的内容
          isSingleSign = false;
          isInChar = true;
          isNoSign = false;
        } else if (msgChars[i] == ':') {
          // 主键与值的分隔符
          if (isParseKey) {
            isParseKey = false;
          } else {
            // 遇到分隔符时，肯定为解析主键的状态
            // ，如果不是，说明数据有问题
            continue;
          }
        } else if (msgChars[i] == ',') {
          if (hasSetObject) {
            // 已经往序列中设置了对象，在这里就不能从缓存中拿空字符串作为元素设置到序列中
            hasSetObject = false;
          } else {
            if (isParseKey) {
              // 当前在解析key值，是不应该进到这里来的
              continue;
            }
            if (key.size() < 1) {
              // 没有key值，无效数据
              continue;
            }
            // 元素分隔符
            if (isNoSign) {
              // 无字符串定义符号的数据，强制转换为数字字符串
              json.mapValue.put(key.toString(), filteReserveChar(value.toCharArray()));
            } else {
              // 普通字符串，过滤掉 null关键字
              json.mapValue.put(key.toString(), value.toString());
            }
          }
          isInChar = false;
          isSingleSign = false;
          isNoSign = false;
          isParseKey = true;
          key.reset();
          value.reset();
        } else if (msgChars[i] == '[') {
          // 元素为序列，解析子序列
          if (isParseKey) {
            // 当前在解析key值，是不应该进到这里来的
            continue;
          }
          if (key.size() < 1) {
            // 没有key值，无效数据
            continue;
          }
          // 构建子对象
          Json cJson = new Json();
          cJson.parent = this;
          cJson.isList = true;
          // 放入容器
          json.mapValue.put(key.toString(), cJson);
          i = parseList(msgChars, i + 1, cJson);
          isInChar = false;
          isSingleSign = false;
          isNoSign = false;
          isParseKey = true;
          hasSetObject = true; // 标记已经往序列中设置了对象
          key.reset();
          value.reset();
          continue;
        } else if (msgChars[i] == '{') {
          // 元素为容器，解析子容器
          if (isParseKey) {
            // 当前在解析key值，是不应该进到这里来的
            continue;
          }
          if (key.size() < 1) {
            // 没有key值，无效数据
            continue;
          }
          // 构建子对象
          Json cJson = new Json();
          cJson.parent = this;
          cJson.isList = false;
          // 放入容器
          json.mapValue.put(key.toString(), cJson);
          i = parseMap(msgChars, i + 1, cJson);
          isInChar = false;
          isSingleSign = false;
          isNoSign = false;
          isParseKey = false;
          hasSetObject = true; // 标记已经往序列中设置了对象
          key.reset();
          value.reset();
          continue;
        } else if (msgChars[i] == '}') {
          // 序列解析完毕
          if (isParseKey) {
            // 当前在解析key值，是不应该进到这里来的
            return i;
          }
          if (key.size() < 1) {
            // 没有key值，无效数据
            return i;
          }
          if (hasSetObject) {
            // 已经往序列中设置了对象，在这里就不能从缓存中拿空字符串作为元素设置到序列中
            hasSetObject = false;
          } else {
            if (isNoSign) {
              // 无字符串定义符号的数据，强制转换为数字字符串
              json.mapValue.put(key.toString(), filteReserveChar(value.toCharArray()));
            } else {
              // 普通字符串，过滤掉 null关键字
              json.mapValue.put(key.toString(), value.toString());
            }
          }
          return i;
        } else {
          if (isParseKey) {
            // 主键必须为字符串 过滤掉无用的字符
            if (msgChars[i] == ' ' || msgChars[i] == '\t' || msgChars[i] == '\r' || msgChars[i] == '\n') {
              continue;
            }
            // 为字符串（没有用单引号或双引号定义的字符串）
            isInChar = true;
            isSingleSign = false;
            isNoSign = true;
            hasSetObject = false;
            key.write(msgChars[i]);
          } else {
            // 为字符串（没有用单引号或双引号定义的字符串）
            isInChar = true;
            isSingleSign = false;
            isNoSign = true;
            hasSetObject = false;
            value.reset();
            value.write(msgChars[i]);
          }
        }
      }
    }
    return msgChars.length;
  }

  /**
   * 解析Json序列
   * 马宝刚
   * 2013-7-18 上午9:56:08
   * @param msgChars     待解析的字符数组
   * @param index       解析起始位
   * @param json         当前处理对象
   * @return             解析后的位置
   */
  protected int parseList(char[] msgChars, int index, Json json) {
    if (msgChars.length <= index || msgChars[index] == ']') {
      return index;
    }
    if (json.listValue == null) {
      json.listValue = new ArrayList<Object>();
    }
    json.isList = true;

    boolean isInChar = false; // 是否为解析字符串模式
    boolean isSingleSign = false; // 字符串是否采用单引号定义
    boolean isNoSign = false; // 是否为无定义符号字符串（通常为数字，不用单引号或双引号定义）
    boolean isSpecSign = false; // 是否为转译字符
    boolean isBeginParseEle = false; // 是否开始解析元素
    boolean hasSetObject = false; // 是否已经往序列中设置了对象

    CharArrayWriter value = new CharArrayWriter(); // 值

    for (int i = index; i < msgChars.length; i++) {
      if (isInChar) {
        // 正在解析字符串中的内容
        if (msgChars[i] == '\\') {
          // 标记为转译字符
          isSpecSign = true;
        } else if (isSpecSign) {
          value.write(msgChars[i]);
          isSpecSign = false;
          isBeginParseEle = true;
        } else if ((msgChars[i] == '\'' && isSingleSign) || (msgChars[i] == '\"' && !isSingleSign)) {
          // 标记字符串结束
          isInChar = false;
          isSingleSign = false;
        } else if (msgChars[i] == ',' || msgChars[i] == ']') {
          if (isNoSign) {
            // 在没有引号做字符串定义时，遇到逗号，标记字符串结束
            i--; // 退回一个字符，由解析定义字符部分处理
            isInChar = false;
            isSingleSign = false;
          } else {
            // 该逗号或中括号是在字符串内的
            value.write(msgChars[i]);
            isBeginParseEle = true;
          }
        } else {
          // 字符串中的内容
          value.write(msgChars[i]);
          isBeginParseEle = true;
        }
      } else {
        if (msgChars[i] > 0 && msgChars[i] < 33) {
          continue; // 过滤控制字符
        } else if (msgChars[i] == '\'') {
          // 单引号定义字符串，开始解析字符串中的内容
          isSingleSign = true;
          isInChar = true;
          isNoSign = false;
        } else if (msgChars[i] == '\"') {
          // 双引号定义字符串，开始解析字符串中的内容
          isSingleSign = false;
          isInChar = true;
          isNoSign = false;
        } else if (msgChars[i] == ',') {
          if (hasSetObject) {
            // 已经往序列中设置了对象，在这里就不能从缓存中拿空字符串作为元素设置到序列中
            hasSetObject = false;
          } else {
            // 元素分隔符
            if (isNoSign) {
              // 无字符串定义符号的数据，强制转换为数字字符串
              json.listValue.add(filteReserveChar(value.toCharArray()));
            } else {
              // 普通字符串，过滤掉 null关键字
              json.listValue.add(value.toString());
            }
          }
          isInChar = false;
          isSingleSign = false;
          isNoSign = false;
          isBeginParseEle = true;
          value.reset();
        } else if (msgChars[i] == '[') {
          // 元素为序列，解析子序列

          // 构造子对象
          Json cJson = new Json();
          cJson.parent = this;
          cJson.isList = true;
          // 将子对象加入序列
          json.listValue.add(cJson);
          i = parseList(msgChars, i + 1, cJson);

          isInChar = false;
          isSingleSign = false;
          isNoSign = false;
          isBeginParseEle = false;
          hasSetObject = true; // 标记已经往序列中设置了对象
          value.reset();
          continue;
        } else if (msgChars[i] == '{') {
          // 元素为容器，解析子容器

          // 构造子对象
          Json cJson = new Json();
          cJson.parent = this;
          cJson.isList = false;
          // 将子对象加入序列
          json.listValue.add(cJson);

          i = parseMap(msgChars, i + 1, cJson);
          isInChar = false;
          isSingleSign = false;
          isNoSign = false;
          isBeginParseEle = false;
          hasSetObject = true; // 标记已经往序列中设置了对象
          value.reset();
          continue;
        } else if (msgChars[i] == ']') {
          if (hasSetObject) {
            // 已经往序列中设置了对象，在这里就不能从缓存中拿空字符串作为元素设置到序列中
            hasSetObject = false;
          } else {
            // 序列解析完毕
            if (isBeginParseEle) {
              if (isNoSign) {
                // 无字符串定义符号的数据，强制转换为数字字符串
                json.listValue.add(filteReserveChar(value.toCharArray()));
              } else {
                // 普通字符串，过滤掉 null关键字
                json.listValue.add(value.toString());
              }
            }
          }
          return i;
        } else {
          // 为字符串（没有用单引号或双引号定义的字符串）
          isInChar = true;
          isSingleSign = false;
          isNoSign = true;
          isBeginParseEle = true;
          hasSetObject = false;
          value.reset();
          value.write(msgChars[i]);
        }
      }
    }
    return msgChars.length;
  }
  
  
  /**
   * 过滤掉数字字符串或逻辑关键字中的其它字符
   * 
   * 如果过滤后发现该字符串不是数字或者不是逻辑关键字，则返回0
   * mbg
   * 2013-7-18 上午10:08:47
   * @param chars 待过滤的字符数组
   * @return 过滤后的字符串
   */
  protected String filteReserveChar(char[] chars) {
    int start = 0; // 开头起始位置
    // 准备去掉开头的控制字符
    for (int i = 0; i < chars.length; i++) {
      if (chars[i] > 0 && chars[i] < 33) {
        // 属于控制字符
        start++;
      } else {
        break;
      }
    }
    int len = chars.length - start; // 截取字符长度
    // 去掉结尾的控制字符
    for (int i = chars.length - 1; i > -1; i--) {
      if (chars[i] > 0 && chars[i] < 33) {
        // 属于控制字符
        len--;
      } else {
        break;
      }
    }
    // 构建返回信息
    String reStr = new String(chars, start, len);
    if ("null".equalsIgnoreCase(reStr)) {
      setAllowNullValue(true);
      setNullKey(reStr);
      return null;
    }
    return reStr;
  }
  
  /**
   * 获取当前级别中，指定主键的子对象
   * @param key 主键
   * @return        子对象
   * 2014年4月10日
   * @author 马宝刚
   */
  public Json getChildJson(String key) {
    if (mapValue == null) {
      return putJson(key);
    }
    // 获取返回值
    Object reObj = mapValue.get(key);
    if (reObj == null) {
      return putJson(key);
    }
    if (reObj instanceof Json) {
      return (Json) reObj;
    }
    return new Json();
  }
  
  /**
   * 获取当前级别中，指定主键的子对象
   * @param key 主键
   * @return 子对象
   * 2016年10月2日
   * @author MBG
   */
  public Json child(String key) {
    return getChildJson(key);
  }
  
  /**
   * 获取当前级别中，指定主键的子对象
   * @param key 主键
   * @return 子对象
   * 2016年10月2日
   * @author MBG
   */
  public Json getJson(String key) {
    return getChildJson(key);
  }
  
  /**
   * 返回当前节点的主键序列
   * @return 当前节点的主键序列
   * 2019年3月5日
   * @author MBG
   */
  public List<String> keyList(){
    //构建返回值
    List<String> reList = new ArrayList<String>();
    if(mapValue==null) {
      return reList;
    }
    reList.addAll(mapValue.keySet());
    return reList;
  }
  
  /**
   * 返回当前节点的主键数组
   * @return 当前节点的主键数组
   * 2019年3月5日
   * @author MBG
   */
  public String[] keys() {
    if(mapValue==null) {
      return new String[0];
    }
    //获取当前节点主键序列
    List<String> list = keyList();
    //构建返回值
    String[] reArrl = new String[list.size()];
    list.toArray(reArrl);
    return reArrl;
  }
  
  /**
   * 获取当前级别中，指定主键对应的值
   * @param key 主键
   * @return 对应的值，可能是空（四大皆空），可能是字符串，可能是Json对象
   * 2016年1月26日
   * @author 马宝刚
   */
  public Object get(String key) {
    if (mapValue == null) {
      return null;
    }
    return mapValue.get(key);
  }
  
  /**
   * 通过索引值获取序列中指定的子对象元素
   * @param index     元素索引
   * @return          子对象元素
   * 2015年3月18日
   * @author 马宝刚
   */
  public Json getChildJson(int index) {
    if (index < 0 || getChildList().size() <= index) {
      return new Json();
    }
    // 获取结果
    Object reObj = getChildList().get(index);
    if (reObj == null || !(reObj instanceof Json)) {
      return new Json();
    }
    return (Json) reObj;
  }

  /**
   * 通过索引值获取序列中指定子Json元素或最终元素
   * @param index 元素索引
   * @return      指定子Json元素，或指定最中元素
   * 2015年3月18日
   * @author 马宝刚
   */
  public Json child(int index) {
    return getChildJson(index);
  }
  
  /**
   * 通过索引值获取序列中指定的子对象元素
   * @param index   元素索引
   * @return        子对象元素
   * 2015年3月18日
   * @author 马宝刚
   */
  public Json getJson(int index) {
    return getChildJson(index);
  }
  
  /**
   * 获取当前级别中指定主键值
   * @param key 主键
   * @return         对应值
   * 2014年4月10日
   * @author 马宝刚
   */
  public String getValue(String key) {
    if (mapValue == null) {
      return "";
    }
    // 获取返回值
    Object reObj = mapValue.get(key);
    if (reObj == null) {
      return "";
    }
    if (reObj instanceof String) {
      return (String) reObj;
    }
    return "";
  }
  
  /**
   * 获取当前级别中指定主键值
   * @param key 主键
   * @return         对应值
   * 2014年4月10日
   * @author 马宝刚
   */
  public String value(String key) {
    return getValue(key);
  }
  
  /**
   * 设置一个新值到当前节点中 功能同 put方法
   * @param key    主键
   * @param value  值
   * @return       类实例
   * 2016年12月1日
   * @author MBG
   */
  public Json value(String key,Object value) {
    put(key,value);
    return this;
  }
  
  /**
   * 获取当前级别中指定索引值
   * @param index 索引序号
   * @return 对应值
   * 2016年1月7日
   * @author 马宝刚
   */
  public String getValue(int index) {
    if (index < 0 || listValue == null || index >= listValue.size()) {
      return "";
    }
    // 获取返回值
    Object reObj = listValue.get(index);
    if (reObj instanceof String) {
      return (String) reObj;
    }
    return "";
  }
  
  /**
   * 获取当前级别中指定索引值
   * @param index 索引序号
   * @return 对应值
   * 2016年1月7日
   * @author 马宝刚
   */
  public String value(int index) {
    return getValue(index);
  }
  
  /**
   * 获取返回值
   * @param index 索引号
   * @return 可能是字符串，可能是Json对象，可能是命运，可能为空
   * 2016年1月26日
   * @author 马宝刚
   */
  public Object get(int index) {
    if (index < 0 || listValue == null || index >= listValue.size()) {
      return null;
    }
    // 获取返回值
    return listValue.get(index);
  }
  
  /**
   * 将当前Json对象（序列值的）转换为字符串序列
   * @return 字符串序列
   * 2016年10月25日
   * @author MBG
   */
  public List<String> toList(){
    if(listValue==null) {
      return new ArrayList<String>();
    }
    //构建返回值
    List<String> reList = new ArrayList<String>();
    for(int i=0;i<listValue.size();i++) {
      reList.add(listValue.get(i).toString());
    }
    return reList;
  }
  
  /**
   * 将当前Json对象（Map值的）转换为Map<String,String>容器
   * @return Map<String,String>容器
   * 2016年10月25日
   * @author MBG
   */
  public Map<String,String> toMap(){
    if(mapValue==null) {
      return new LinkedHashMap<String,String>();
    }
    //构建返回值
    Map<String,String> reMap = new HashMap<String,String>();
    Iterator<String> keyIterator = mapValue.keySet().iterator(); //主键序列
    String key;   //主键元素
    Object value; //值元素
    while(keyIterator.hasNext()) {
      key = keyIterator.next();
      value = mapValue.get(key);
      if(value==null) {
        reMap.put(key,null);
      }else {
        reMap.put(key,value.toString());
      }
    }
    return reMap;
  }
  
  /**
   * 获取当前级别的数组序列
   * @return 数组序列
   * 2014年4月10日
   * @author 马宝刚
   */
  @SuppressWarnings("rawtypes")
  public List getChildList() {
    if (listValue == null) {
      return new ArrayList<Object>();
    }
    return listValue;
  }

  /**
   * 获取当前级别的数组序列 （没有这个英文单词，但看起来很直观。也可以使用children方法）
   * @return 数组序列
   * 2014年4月10日
   * @author 马宝刚
   */
  @SuppressWarnings("rawtypes")
  public List childs() {
    if (listValue == null) {
      return new ArrayList<Object>();
    }
    return listValue;
  }
  
  /**
   * 获取当前级别的数组序列
   * @return 数组序列
   * 2014年4月10日
   * @author 马宝刚
   */
  @SuppressWarnings("rawtypes")
  public List children() {
    if (listValue == null) {
      return new ArrayList<Object>();
    }
    return listValue;
  }
  
  /**
   * 获取当前级别的对照容器 简称：valueMap()
   * @return 当前级别的对照容器 2014年6月25日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Map<String, Object> getValueMap() {
    if (mapValue == null) {
      return new HashMap();
    }
    return mapValue;
  }

  /**
   * 获取当前级别的对照容器 全称：getValueMap()
   * @return 当前级别的对照容器 2014年6月25日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Map<String, Object> valueMap() {
    if (mapValue == null) {
      return new HashMap();
    }
    return mapValue;
  }
    
  /**
   * 获取当前级别的对照容器 简称：valueMap(key)
   * @param key 子节点主键
   * @return 当前级别的对照容器 2014年6月25日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Map<String, Object> getValueMap(String key) {
    // 获取其子节点
    Json child = getChildJson(key);
    if (child.isEmpty() || child.isList) {
      return new HashMap();
    }
    return child.getValueMap();
  }

  /**
   * 获取当前级别的对照容器 全称：getValueMap(key)
   * @param key 子节点主键
   * @return 当前级别的对照容器 2014年6月25日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Map<String, Object> valueMap(String key) {
    // 获取其子节点
    Json child = getChildJson(key);
    if (child.isEmpty() || child.isList) {
      return new HashMap();
    }
    return child.valueMap();
  }

  /**
   * 获取子节点数组 简称： valueList(key);
   * @param key 主键
   * @return 值数组 2017年4月9日
   * @author MBG
   */
  @SuppressWarnings("rawtypes")
  public List getValueList(String key) {
    // 获取其子节点
    Json child = getChildJson(key);
    if (child.isEmpty() || !child.isList) {
      return new ArrayList();
    }
    return child.getChildList();
  }

  /**
   * 获取子节点数组 全称：getValueList(key)
   * @param key 主键
   * @return 值数组 2017年4月9日
   * @author MBG
   */
  @SuppressWarnings("rawtypes")
  public List valueList(String key) {
    // 获取其子节点
    Json child = getChildJson(key);
    if (child.isEmpty() || !child.isList) {
      return new ArrayList();
    }
    return child.getChildList();
  }
    
  /**
   * 从序列中移出指定索引值
   * @param index 指定索引
   * @return 移出后的值 2015年3月17日
   * @author 马宝刚
   */
  public Object remove(int index) {
    return getChildList().remove(index);
  }

  /**
   * 从对照容器中移出指定主键的值
   * @param key 主键
   * @return 移出后的值 2015年3月17日
   * @author 马宝刚
   */
  public Object remove(String key) {
    return getValueMap().remove(key);
  }

  /**
   * 将Json序列转换为json字符串 
   * @param json 对象
   * @return json字符串
   */
  protected String listString(Json json) {
    // 构建返回值
    StringBuffer sbf = new StringBuffer("[");
    if (json != null && json.listValue != null) {
      boolean noFirstEle = false; // 是否不是第一个元素
      boolean allowNullValue = json.isAllowNullValue(); // 如果值为空，是否返回null关键字而非""
      boolean noFormat = json.isNoFormat(); // 输出的json中的值是否都不带双引号
      boolean standardFormat = json.isStandardFormat(); // 输出的json是否为标准格式
      for (Object ele : json.listValue) {
        if (noFirstEle) {
          sbf.append(",");
        } else {
          noFirstEle = true;
        }

        if (ele == null) {
          if (allowNullValue) {
            sbf.append(getNullKey());
          } else {
            sbf.append("\"\"");
          }
        } else {
          if (ele instanceof Json) {
            // Json 类型
            sbf.append(ele);
          } else if (ele instanceof Integer || ele instanceof Long || ele instanceof Float || ele instanceof Double) {
            // 如果是数字型的，就不加分隔符了，就这么定了
            sbf.append(ele);
          } else if (ele instanceof Boolean) {
            if ((Boolean) ele) {
              sbf.append(true);
            } else {
              sbf.append(false);
            }
          } else {
            if (noFormat) {
              // 如果noFormat为true，无论内部的值是什么，都不加双引号分隔符
              // 比如返回javascript中需要用到的 click : doSearch 中，doSearch 就不能加双引号
              // if(checkNumber((String)ele) || ele.equals("true") || ele.equals("false")) {
              // sbf.append(ele);
              // }else {
              // sbf.append(delimiter).append(ele).append(delimiter);
              // }
              sbf.append(ele);
            } else if (standardFormat) {
              // 是否输出标准json格式值
              if (checkNumber((String) ele) || ele.toString().equalsIgnoreCase("true")
                  || ele.toString().equalsIgnoreCase("false")) {
                sbf.append(ele);
              } else {
                sbf.append(delimiter).append(ele).append(delimiter);
              }
            } else {
              // 默认都按String类型处理
              sbf.append(delimiter).append(filterStr(ele))
                  .append(delimiter);
            }
          }
        }
      }
    }
    return sbf.append("]").toString();
  }

  /**
   * 将Json容器转换为json字符串
   * 马宝刚
   * 2013-7-17 下午3:57:18
   * @param json json
   * @return json字符串
   */
   protected String mapString(Json json) {
    if (json.mapValue == null) {
      return "{}";
    }
    // 构建返回值
    StringBuffer sbf = new StringBuffer("{");
    // 获取容器主键迭代
    Iterator<String> keyIterator = json.mapValue.keySet().iterator();
    String key; // 主键元素
    Object value; // 参数值
    boolean noFirstEle = false; // 是否不是第一个元素
    boolean allowNullValue = json.isAllowNullValue(); // 如果值为空，是否返回null关键字而非""
    boolean noFormat = json.isNoFormat(); // 输出的json中的值是否都不加双引号
    boolean standardFormat = json.isStandardFormat(); // 输出的json是否为标准格式
    while (keyIterator.hasNext()) {
      key = keyIterator.next();
      if (noFirstEle) {
        sbf.append(",");
      } else {
        noFirstEle = true;
      }
      // 获取参数值
      value = json.mapValue.get(key);
      // 添加参数头
      sbf.append(delimiter).append(filterStr(key)).append(delimiter + ":");

      if (value == null) {
        if (allowNullValue) {
          sbf.append(getNullKey());
        } else {
          sbf.append(delimiter).append(delimiter);
        }
      } else {
        if (value instanceof Json) {
          sbf.append(value);
        } else if (value instanceof Integer || value instanceof Long || value instanceof Float || value instanceof Double) {
          // 如果是数字型的，就不加分隔符了，就这么定了
          sbf.append(value);
        } else if (value instanceof Boolean) {
          if ((Boolean) value) {
            sbf.append(true);
          } else {
            sbf.append(false);
          }
        } else {
          if (noFormat) {
            // 如果outNoStringFormat为true，无论内部的值是什么，都不加双引号分隔符
            // 比如返回javascript中需要用到的 click : doSearch 中，doSearch 就不能加双引号
            // if(checkNumber((String)value) || value.equals("true") ||
            // value.equals("false")) {
            // sbf.append(value);
            // }else {
            // sbf.append(delimiter).append(value).append(delimiter);
            // }
            sbf.append(value);
          } else if (standardFormat) {
            if (checkNumber((String) value) || value.toString().equalsIgnoreCase("true")
                || value.toString().equalsIgnoreCase("false")) {
              sbf.append(value);
            } else {
              sbf.append(delimiter).append(filterStr(value)).append(delimiter);
            }
          } else {
            // 默认都按String类型处理
            sbf.append(delimiter).append(filterStr(value))
                .append(delimiter);
          }
        }
      }
    }
    return sbf.append("}").toString();
  }
  
  /**
   * 检测值是否为数字 （正负号 数字 小数点）
   * mbg
   * 2013-7-17 下午4:12:58
   * @param value 待检测值
   * @return true为数字
   */
  protected boolean checkNumber(String value) {
    return value.matches("^(\\-|\\+)?\\d+(\\.\\d+)?$");
  }
  
  /**
   * 覆盖方法
   * 返回Json字符串值
   */
  @Override
    public String toString() {
    if(isList) {
      return listString(this);
    }
    return mapString(this);
  }
  
  /**
   * 将指定json对象中的内容设置到当前Json中
   * @param json 指定json对象
   * @return 当前类实例
   * 2015年2月13日
   * @author 马宝刚
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Json setJson(Json json) {
    if (json == null) {
      return this;
    }
    if (json.listValue != null && json.listValue.size() > 0) {
      isList = true;
      if (listValue == null) {
        listValue = new ArrayList<Object>();
      }
      listValue.addAll(json.listValue);
    }
    if (json.mapValue != null && json.mapValue.size() > 0) {
      isList = false;
      if (mapValue == null) {
        mapValue = new LinkedHashMap();
      }
      mapValue.putAll(json.mapValue);
    }
    return this;
  }
  
  /**
   * 删除空主键的值（只针对Map型容器）
   * @return 当前类实例
   * 2016年1月24日
   * @author 马宝刚
   */
  public Json clearEmpty() {
    if (mapValue == null) {
      return this;
    }
    // 主键迭代
    Iterator<String> keyIterator = mapValue.keySet().iterator();
    String key; // 主键元素
    Object value; // 主键对应值
    Json jsonVal; // 对应的值如果是json
    while (keyIterator.hasNext()) {
      key = keyIterator.next();
      value = mapValue.get(key);
      if (value instanceof Json) {
        jsonVal = (Json) value;
        jsonVal.clearEmpty();
        if (jsonVal.isEmpty()) {
          mapValue.remove(key);
        }
      } else if (value instanceof String) {
        if (value == null || ((String) value).length() < 1) {
          mapValue.remove(key);
        }
      } else if (value == null) {
        mapValue.remove(key);
      }
    }
    return this;
  }
  
  /**
   * 将Json对象转换为Java传统对象
   * @return Java传统对象 比如：Map<String,Map>  Map<String,List<Map>> List<Map> List<String>
   *          具体转换为什么对象，还得看Json报文字符串的格式
   * 2017年11月27日
   * @author MBG
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public Object toObject() {
    if (isList) {
      // 构建返回值
      List reList = new ArrayList();
      if (listValue != null) {
        for (Object ele : listValue) {
          if (ele instanceof String) {
            reList.add(ele);
          } else {
            reList.add(((Json) ele).toObject());
          }
        }
      }
      return reList;
    }
    // 构建返回值
    Map reMap = new LinkedHashMap();
    if (mapValue != null) {
      // 参数主键迭代
      Iterator<String> keyIterator = mapValue.keySet().iterator();
      String key; // 主键元素
      Object value; // 参数值
      while (keyIterator.hasNext()) {
        key = keyIterator.next();
        value = mapValue.get(key);
        if (value instanceof String) {
          reMap.put(key, value);
        } else {
          reMap.put(key, ((Json) value).toObject());
        }
      }
    }
    return reMap;
  }
  
  /**
   * 返回json内容中的状态值（key：status）
   * @return 状态值
   * 2018年1月18日
   * @author MBG
   */
  public int status() {
    try {
      return Integer.parseInt(value("status"));
    }catch(Exception e) {}
    return 0;
  }
  
  /**
   * 返回json内容中的状态值（默认key：status）
   * @param key 状态值主键
   * @return 状态值
   * 2018年1月18日
   * @author MBG
   */
  public int status(String key) {
    if(key==null || key.length()<1) {
      key = "status";
    }
    try {
      return Integer.parseInt(value("status"));
    }catch(Exception e) {}
    return 0;
  }
  
  /**
   * 返回json内容中的错误说明信息（key：msg）
   * @return 错误说明信息
   * 2018年1月18日
   * @author MBG
   */
  public String msg() {
    return value("msg");
  }
  
  /**
   * 返回json内容中的错误说明信息（默认key：msg）
   * @param key 错误说明信息主键
   * @return 错误说明信息
   * 2018年1月18日
   * @author MBG
   */
  public String msg(String key) {
    if(key==null || key.length()<1) {
      key = "status";
    }
    return value(key);
  }
  
  /**
   * 过滤拼装到js字符串中的特殊字符
   * @param obj 待过滤的对象
   * @return    过滤后的字符串
   * 2022年10月20日
   * @author mbg
   */
  private String filterStr(Object obj) {
	  if (obj == null) {
		  return "";
	  }
	  if (obj instanceof java.sql.Timestamp) {
		  return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(((java.sql.Timestamp) obj));
	  }
	  return obj
			  .toString()
			    .replaceAll("(\\\\)", "\\\\\\\\")
			    .replaceAll("(?i)\\n", "\\\\n")
			    .replaceAll("(?i)\\r", "\\\\r")
			    .replaceAll("(\\"+delimiter+")", "\\\\"+delimiter);
  }
  
  /**
   * 将对象强制转换为字符串
   * @param obj 待处理的对象
   * @return 转换后的字符串 2017年7月26日
   * @author MBG
   */
  private String str(Object obj) {
    if (obj == null) {
      return "";
    }
    if (obj instanceof java.sql.Timestamp) {
      return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(((java.sql.Timestamp) obj));
    }
    // 构造返回值
    return String.valueOf(obj);
  }

  /**
   * 除去指定字符串首尾的指定字符
   * @param str      指定字符串
   * @param trimStrs 指定字符（可以是多个字符）
   * @return 处理后的字符串 2014年7月29日
   * @author 椹疂鍒?
   */
  private String trim(String str, String... trimStrs) {
    if (str == null) {
      return "";
    }
    str = str.trim();
    for (int i = 0; i < trimStrs.length; i++) {
      for (String trimStr : trimStrs) {
        if (str.startsWith(trimStr)) {
          str = str.substring(1);
        }
        if (str.endsWith(trimStr)) {
          str = str.substring(0, str.length() - 1);
        }
      }
    }
    return str;
  }
}
